package pattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 描述:动态代理
 *
 *  1.动态代理
 *  代理类在程序运行时创建的代理方式被成为动态代理。 我们上面静态代理的例子中，代理类(studentProxy)是自己定义好的，
 *  在程序运行之前就已经编译完成。然而动态代理，代理类并不是在Java代码中定义的，而是在运行时根据我们在Java代码中的“指示”动态生成的。
 *  相比于静态代理， 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理，而不用修改每个代理类中的方法
 *
 * @author Madison You
 * @created 20:10
 */
public class DynamicProxy {
    public static void main(String[] args) {
        Singerner singerner = new Singerner();
        StoryInvocationHandler storyInvocationHandler = new StoryInvocationHandler(singerner);
        ClassLoader classLoader = DynamicProxy.class.getClassLoader();
        Class<?>[] interfaces = singerner.getClass().getInterfaces();
        Singer singer = (Singer) Proxy.newProxyInstance(classLoader, interfaces, storyInvocationHandler);
        singer.orderSong("就是现在");
        singer.sayGoodBye("拜拜");
    }
}

interface Singer {
    void orderSong(String songName);

    void sayGoodBye(String string);
}

class Singerner implements Singer {

    @Override
    public void orderSong(String songName) {
        System.out.println("唱歌");
    }

    @Override
    public void sayGoodBye(String string) {
        System.out.println("告别");
    }
}

class StoryInvocationHandler implements InvocationHandler {

    private Object object;

    public StoryInvocationHandler(Object o) {
        this.object = o;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前面做的事");
        method.invoke(object, args);
        System.out.println("后面做的事");
        return null;
    }
}
